///  <copyright file="MallowMain.cs" company="Infozoom" author="Stefan Zschocke">
///    You must not remove this notice, or any other, from this software.
///    Otherwise do with it whatever you want.
///    infoZoom may not be made liable for any damages whatsoever 
///    (including, without limitation, damages for loss of business profits, 
///    business interruption, loss of business information or other pecuniary loss)
///    arising out of use of or inability to use the Software
/// </copyright>
using System;

namespace Mallow
{
    /// <summary>
    /// todo: add comments
    /// </summary>
    public class MallowMain
    {
        static bool OneFilePerComponent = false;
        static bool SemanticNames = false;
        static bool AutoGenerateGuids = true;
        static string Directory;
        static string WixDirectory = "TARGETDIR";
        static string SourceFile;
        static string DestFile;
        static string DirAlias;

        /// <summary>
        /// Main entry point.
        /// </summary>
        /// <param name="args"></param>
        /// <returns></returns>
        public static int Main(string[] args)
        {
            if (args.Length == 0)
            {
                PrintHelp();
                return -1;
            }

            if (!ParseCommandLine(args))
            {
                return -1;
            }

            try
            {
                Mallow m = new Mallow(OneFilePerComponent, AutoGenerateGuids, SemanticNames);
                if (SourceFile == null)
                {
                    m.NewDoc(WixDirectory);
                }
                else
                {
                    m.OpenDoc(SourceFile);
                }

                int rv = m.Synch(WixDirectory, Directory, DirAlias);
                if (DestFile != null)
                {
                    m.SaveDoc(DestFile);
                }
                else
                {
                    m.Document.Save(Console.Out);
                }

                return rv;
            }
            catch (Mallow.Exception e)
            {
                System.Console.WriteLine(e);
                System.Console.WriteLine(e.StackTrace);
                return -(int)e.ErrNo;
            }
        }

        public static void PrintHelp()
        {
            Console.WriteLine(" usage:  Mallow.exe [-?] -d directory [-w directoryId] [-s sourcefile] [-t targetfile] [-1] [-g] [-a directoryAlias] [-n]" /* [-da?] [-dd filter] [-df filter] "*/);
            Console.WriteLine();
            Console.WriteLine("  -d  walks the directory tree creating components for all the files");
            Console.WriteLine("  -w  Wix-Directory(Ref) to match against the directory (default is TARGETDIR)");
            Console.WriteLine("  -s  source file to use for incremental synchronization (must be a WiX XML file).");
            Console.WriteLine("  -t  target file to use ");
            Console.WriteLine("  -1  one file per component (default=multiple files");
            Console.WriteLine("  -g  don't generate Guids for components (default=generate guids)");
            Console.WriteLine("  -a  use an alias for the directory in the src-portion of the File-elements");
            Console.WriteLine("  -n  generate semantic Ids for directories, files and components");
            //Console.WriteLine("   -~       replace ~ by _ in short file and directory names to get rid of warning CNDL1044");
            /*
            Console.WriteLine("   -da?     adds one or more attributes to all files recursed");
            Console.WriteLine("      c - checksum");
            Console.WriteLine("      h - hidden");
            Console.WriteLine("      p - compressed");
            Console.WriteLine("      r - read only");
            Console.WriteLine("      s - system");
            Console.WriteLine("      v - vital");
            Console.WriteLine("   -dd      provides a filter for directories recursed");
            Console.WriteLine("   -df      provides a filter for files found in a directory");
            */
            Console.WriteLine("  -?  this help information");
            Console.WriteLine();
            Console.WriteLine("Sample usage:");
            Console.WriteLine(@"First time use for a directory   : Mallow -d c:\somewhere\myFiles -t c:\MyWixProject\files.wxs");
            Console.WriteLine(@"Next time user for same directory: Mallow -d c:\somewhere\myFiles -s c:\MyWixProject\files.wxs -t c:\MyWixProject\files.wxs");
            Console.WriteLine(@"Preprocessor variable: Mallow -d c:\somewhere\myFiles -s c:\MyWixProject\files.wxs -t c:\MyWixProject\files.wxs -a $(var.srcFolder)");
            Console.WriteLine(@" this will set the src of c:\somewhere\myFiles\somefile.txt to $(var.srcFolder)\somefile.txt");
            Console.WriteLine();
            Console.WriteLine("For more information see: http://wix.sourceforge.net");
        }

        private static bool ParseCommandLine(string[] args)
        {
            for (int i = 0; i < args.Length; ++i)
            {
                string arg = args[i];

                if (null == arg || "" == arg)
                {   
                    // skip blank arguments
                    continue;
                }

                if ('-' == arg[0] || '/' == arg[0])
                {
                    string parameter = arg.Substring(1);

                    if ("1" == parameter)
                    {
                        MallowMain.OneFilePerComponent = true;
                    }
                    else if ("n" == parameter)
                    {
                        MallowMain.SemanticNames = true;
                    }
                    else if ("d" == parameter || "dirwalk" == parameter)
                    {
                        if (args.Length <= ++i)
                        {
                            throw new ArgumentException("must specify a directory for parameter", "-d");
                        }
                        MallowMain.Directory = args[i];
                    }
                    else if ("w" == parameter)
                    {
                        if (args.Length <= ++i || args[i][0] == '/' || args[i][0] == '-')
                        {
                            throw new ArgumentException("must specify a wix-directory for parameter", "-w");
                        }
                        MallowMain.WixDirectory = args[i];
                    }
                    else if ("a" == parameter)
                    {
                        if (args.Length <= ++i || args[i][0] == '/' || args[i][0] == '-')
                        {
                            throw new ArgumentException("must specify an alias for parameter", "-a");
                        }
                        MallowMain.DirAlias = args[i];
                    }
                    else if ("?" == parameter || "help" == parameter)
                    {
                        PrintHelp(); return false;
                    }
                    else if ("g" == parameter)
                    {
                        MallowMain.AutoGenerateGuids = false;
                    }
                    else if ("s" == parameter || "source" == parameter)
                    {
                        if (args.Length <= ++i)
                        {
                            throw new ArgumentException("must specify a source file for parameter", "-s");
                        }
                        MallowMain.SourceFile = args[i];
                    }
                    else if ("t" == parameter || "target" == parameter)
                    {
                        if (args.Length <= ++i)
                        {
                            throw new ArgumentException("must specify a target file for parameter", "-t");
                        }
                        MallowMain.DestFile = args[i];
                    }
                }
                else
                {
                    throw new ArgumentException(String.Concat("unexpected argument on command line: ", arg));
                }
            }

            if (Directory == null)
            {
                throw new ArgumentException("must specify a directory to work on", "-d");
            }

            return true;
        }
    }
}
